

###Code for replicating results of ``Can Politicians Say That? What Shapes Public Responses to Speech Scandals?´´
##Journal of Experimental Political Science
#Thomas Gift (UCL) and Carlos X. Lastra-Anadón (IE University)
#Please get in touch for comments via clastra@faculty.ie.edu
#2025.06.24


###Set wd to Data folder
setwd("~/Forbidden speech/JEPSreplicationpackageToshare/Data")  


packages <- c("tidyverse", "readr", "readxl",  "xtable", "coefplot")
installed <- packages %in% rownames(installed.packages())
if (any(!installed)) {
  install.packages(packages[!installed])
}

if (!require("remotes")) {
  install.packages("remotes")
}

library("remotes")
remotes::install_github("jdstorey/qvalue")
remotes::install_github("leeper/cregg")


library(tidyverse)
library(readr)
library(readxl)
library(cregg)
library(xtable)
library(coefplot)
library(qvalue)



#######
#######Processing data
#######

forbiddenspeech.1 <-read.csv("rv-omni-2024-november-b-final-2024-12-09.csv")
forbiddenspeech.2 <-read.csv("rv-omni-2024-december-a.csv")
forbiddenspeech.3 <-read.csv("rv-omni-2024-december-b.csv")

#Stack all three waves
forbiddenspeech <- bind_rows(forbiddenspeech.1, forbiddenspeech.2, forbiddenspeech.3)

# Reshape the data from wide to long format
forbiddenspeech <- forbiddenspeech %>%
  mutate(respid = row_number()) %>%
  relocate(respid)


##Make the suffixes consistent for the DVs
forbiddenspeech$cand_consider_1 <- forbiddenspeech$cand_consider1
forbiddenspeech$cand_consider_2 <- forbiddenspeech$cand_consider2
forbiddenspeech$cand_consider_3 <- forbiddenspeech$cand_consider3

forbiddenspeech$FAVOR_therm_1 <- forbiddenspeech$FAVOR_therm1_cl
forbiddenspeech$FAVOR_therm_2 <- forbiddenspeech$FAVOR_therm2_cl
forbiddenspeech$FAVOR_therm_3 <- forbiddenspeech$FAVOR_therm3_cl


forbiddenspeech$cand_draw_1 <- forbiddenspeech$cand_draw1
forbiddenspeech$cand_draw_2 <- forbiddenspeech$cand_draw2
forbiddenspeech$cand_draw_3 <- forbiddenspeech$cand_draw3


##reshape to make data long
forbiddenspeechlong <- forbiddenspeech %>%
  pivot_longer(
    cols = ends_with(c("_1", "_2", "_3")), # Select columns with _1, _2, _3 suffix
    names_to = c(".value", "round"),      # Split the variable name into base name and round number
    names_pattern = "(.*)_(\\d+)"         # Regex pattern to extract the base name and round
  ) %>%
  mutate(round = as.integer(round))

#Now just drop the suffix of the long version
 forbiddenspeech <- forbiddenspeechlong 

#Create an answerid for each respondent-answer pair
forbiddenspeech <- forbiddenspeech %>%
  mutate(answerid = row_number()) %>%
  relocate(answerid)

      
###Treatment group recoding
###Dividing this into different groups

#Define treatment and control
forbiddenspeech$anycontent <- factor(forbiddenspeech$split,
                                          levels = c(1, 2),
                                          labels = c("Control", "Anycontent"))
table(forbiddenspeech$anycontent )

#Encoding severity, ####Correcting to make sure NAs are captured, 
forbiddenspeech <- forbiddenspeech %>%
  mutate(nature_severity = factor(
    ifelse(is.na(split_treat_severity), "Control", split_treat_severity),
    levels = c(1, 2, 3, 4, "Control"),
    labels = c("Slur", "Stereotype", "Dehumanizing", "Denial", "Control")
  ))
table(forbiddenspeech$nature_severity)

#Encoding target
forbiddenspeech$nature_target <- factor(forbiddenspeech$split_treat_identity,
                                            levels = c(1, 2, 3, 4,5,6,7, 99),
                                            labels = c("Racial","Racial","Racial", "Religious", "Religious", "Gays", "Women","Control"))
table(forbiddenspeech$nature_target)

forbiddenspeech$nature_targetdetailed <- factor(forbiddenspeech$split_treat_identity,
                                                levels = c(1, 2, 3, 4,5,6,7, 99),
                                                labels = c("Blacks", "Hispanics", "Asian", "Jews", "Muslims", "Gays","Women","Control"))

#Encoding reponses
forbiddenspeech$response_simple <- factor(forbiddenspeech$split_treat_response,
                                            levels = c(1, 2, 3, 4,5,6,7,8,9,10, 99),
                                            labels = c("Apology","Apology","Apology", "Excuse", "Excuse", "Excuse", "Defense","Defense","Defense","Nocomment","Control"))

forbiddenspeech$response_detailed <- factor(forbiddenspeech$split_treat_response,
                                          levels = c(1, 2, 3, 4,5,6,7,8,9,10, 99),
                                          labels = c("remorseapology","wokeapology","sorryoffended", "pleadignorance", "misspokeexcuse", "outofcontext", "denywrongdoing","playthevictim","goonattack","nocomment","Control"))

##Encoding Insensitive quote or response quote
forbiddenspeech$insensitive_quote <- factor(forbiddenspeech$split_treat_quote,
                                              levels = c(1, 2, 9),
                                              labels = c("quote1","quote2","Control"))


##Encoding Time
forbiddenspeech$timecomments <- factor(forbiddenspeech$split_treat_time,
                                              levels = c(1, 2,9),
                                              labels = c("yesterday","fiveyearsago","Control"))

##Encoding Planned
forbiddenspeech$planned <- factor(forbiddenspeech$split_treat_planned,
                                         levels = c(1, 2,9),
                                         labels = c("planned","unplanned","Control"))

##Encoding History
forbiddenspeech$history <- factor(forbiddenspeech$split_treat_history,
                                   levels = c(1, 2,9),
                                   labels = c("commentsbefore","nevercomments","Control"))


####Coding DVs
forbiddenspeech <-forbiddenspeech %>%
  mutate(
    wouldconsidernotvoting = case_when(
      cand_consider==1  ~ 0,
      cand_consider==2~ 1,
      TRUE ~ NA
    )
  )

#Alternative DVs: thermometer, objectionable
forbiddenspeech$thermometer<-forbiddenspeech$FAVOR_therm
forbiddenspeech$objectionable<-forbiddenspeech$cand_draw

#Incongruence of different types, respondent-candidate
#Party
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    incongparty_responscandidate = case_when(
      pid3==2 & split_party==1  ~ 1, ##Candidate Democrat, resp republican
      pid3==1  & split_party==2  ~ 1, ##Candidate Republican, resp democrat
      pid3==1 & split_party==1  ~ 0, ##Candidate Democrat, resp republican
      pid3==2  & split_party==2  ~ 0, ##Candidate Republican, resp democrat
      TRUE ~ NA
    )
  )

#Race
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    incongrace_responscandidate = case_when(
      split_race==4 & race==1 ~ 0, ##Candidate white
      split_race==2 & race==2 ~ 0, ##Candidate black
      split_race==3 & race==3 ~ 0, ##Candidate hispanic
      split_race==1 & race==4 ~ 0, ##Candidate asian
      TRUE ~ 1
    )
  )

#Gender
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    inconggender_responscandidate = case_when(
      split_genderage==1 & gender==1  ~ 1, ##Male, female candidate
      split_genderage==3 & gender==1  ~ 1, ##Male, female candidate
      split_genderage==2 & gender==2 ~ 1, ##Female, male candidate
      split_genderage==4 & gender==2  ~ 1, ##Female, male candidate
      TRUE ~ 0
    )
  )

#Age
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    incongage_responscandidate = case_when(
      split_genderage==1 & age5>3  ~ 1, #young candidate, older respondent
      split_genderage==2 & age5>3  ~ 1, #young candidate,older respondent
      split_genderage==3 & age5<3~ 1, ##old candidate, younger respondent
      split_genderage==4 & age5<3  ~ 1, ##old candidate, younger respondent
      TRUE ~ 0
    )
  )


forbiddenspeech$incongparty_responscandidate <- factor(forbiddenspeech$incongparty_responscandidate, levels = c("1", "0"))
forbiddenspeech$incongrace_responscandidate <- factor(forbiddenspeech$incongrace_responscandidate, levels = c("1", "0"))
forbiddenspeech$inconggender_responscandidate <- factor(forbiddenspeech$inconggender_responscandidate, levels = c("1", "0"))
forbiddenspeech$incongage_responscandidate <- factor(forbiddenspeech$incongage_responscandidate, levels = c("1", "0"))

#Coding congruence response target
#Race
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    congrace_respontarget = case_when(
      #split_treat_identity==4 & race==1 ~ 1, ## white
      split_treat_identity==1 & race==2 ~ 1, ## black
      split_treat_identity==2 & race==3 ~ 1, ## hispanic
      split_treat_identity==3 & race==4 ~ 1, ## asian
      TRUE ~ 0 ) )


#Religion
      forbiddenspeech <- forbiddenspeech %>%
        mutate(
          congreligion_respontarget = case_when(
            split_treat_identity==4 & religpew==5 ~ 1, ## Jews
            split_treat_identity==5 & religpew==6 ~ 1, ## Muslims
            TRUE ~ 0
          )
        )
      
#Sexual orientation
      forbiddenspeech <- forbiddenspeech %>%
        mutate(
          congsexorientation_respontarget = case_when(
            split_treat_identity==6 & sexuality>1 & sexuality<6 ~ 1, ## Gays and other type of sexual orientation
            TRUE ~ 0
          )
        )
      
      
#Gender
  forbiddenspeech <- forbiddenspeech %>%
        mutate(
          conggender_responstarget = case_when(
            split_treat_identity==7 & gender==2 ~ 1, ##Female and female target
            TRUE ~ 0
          )
        )

###Recoding of treatment groups-respondent combinations
###Coding degree of congruence respondent-target
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    cong_responstarget = case_when(
      gender==2 & nature_target =="Women"  ~ 1,
      race!=1 & nature_target =="Racial" ~ 1,
      sexuality!=1 & nature_target =="Gays" ~ 1,
      TRUE ~ 0
    )
  )

#coding number of mitigating circumstances
forbiddenspeech<-forbiddenspeech %>%
  mutate(
    fiveyears = case_when(
      split_treat_time==1 ~ 0,
      split_treat_time==2 ~ 1,
      TRUE ~ NA
    )
  )

forbiddenspeech<-forbiddenspeech %>%
  mutate(
    frequent = case_when(
      split_treat_history==1 ~ 1,
      split_treat_history==2 ~ 0,
      TRUE ~ NA
    )
  )

forbiddenspeech<-forbiddenspeech %>%
     mutate(
         facplanned = case_when(
             planned=="planned" ~ 1,
             planned=="unplanned" ~ 0,
             TRUE ~ NA
  )
  )


####Counting mitigating circumstances
forbiddenspeech <- forbiddenspeech %>%
  mutate( mitig_circum = fiveyears + 1-facplanned+ +1-frequent
  )

forbiddenspeech <- forbiddenspeech %>%
  mutate( agg_circum =  case_when(
    mitig_circum==0  ~ 3,
    mitig_circum==1  ~ 2,
    mitig_circum==2  ~ 1,
    mitig_circum==3  ~ 0 )
  )


#### Congruence between respondent candidate
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    cong_responscandidate = case_when(
      split_genderage==2 & gender==1  ~ 1, ##Male
      split_genderage==4 & gender==1  ~ 1, ##Male
      split_genderage==1 & gender>1  ~ 1, ##Female
      split_genderage==3 & gender>1  ~ 1, ##Female
      split_race==4 & race==1 ~ 1, ##White
      split_race<4 & race>1 ~ 1, ##Nonwhite
      TRUE ~ 0
    )
  )


forbiddenspeech <- forbiddenspeech %>%
  mutate(
    white_pol = case_when(
      split_race==4  ~ 1, ##White
      split_race<4  ~ 0, ##Nonwhite
      TRUE ~ 0
    )
  )

forbiddenspeech <- forbiddenspeech %>%
  mutate(
    man_pol = case_when(
      split_genderage==2   ~ 1, ##Male
      split_genderage==4   ~ 1, ##Male
      split_genderage==1   ~ 0, ##FeMale
      split_genderage==3  ~ 0, ##FeMale
      TRUE ~ 0
    )
  )


forbiddenspeech <- forbiddenspeech %>%
  mutate(
    millennial_pol = case_when(
      split_genderage==1   ~ 1, 
      split_genderage==2   ~ 1, 
      split_genderage==3   ~ 0, 
      split_genderage==4  ~ 0, 
      TRUE ~ 0
    )
  )


#Save cleaned data as CSV file
write.csv(forbiddenspeech,"forbiddenspeech.csv")



##############
###Analyses
##############

##############
##Set folder for output
##############
# Create a new directory named "Output" if it doesn't already exist
if (!dir.exists("../Output")) {
  dir.create("../Output")
}
setwd("../Output")


########Common figures plot themes
conjoint_theme<- theme(    text = element_text(size = 14),  # Increase font size
                           axis.text = element_text(size = 12),  # Increase axis text size
                           axis.title = element_text(size = 14),  # Increase axis title size
                           legend.text = element_text(size = 12),  # Increase legend text size
                           legend.title = element_text(size = 14),  # Increase legend title size
                           legend.position="none",
                           plot.title = element_text(size = 16),  # Increase plot title size
                           panel.border = element_rect(size = 1.5, color = "black"),  # Increase panel border size
                           axis.title.x = element_blank(),
                           plot.margin = margin(1, 1, 1, 1, unit = "cm")  # Adjust plot margins
) 



plot_theme<- theme(    text = element_text(size = 14),  # Increase font size
                       axis.text = element_text(size = 12),  # Increase axis text size
                       axis.title = element_text(size = 14),  # Increase axis title size
                       legend.text = element_text(size = 12),  # Increase legend text size
                       legend.title = element_text(size = 14),  # Increase legend title size
                       legend.position="none",
                       plot.title = element_text(size = 16),  # Increase plot title size
                       panel.border = element_rect(size = 1.5, color = "black"),  # Increase panel border size
                       axis.title.x = element_blank(),
                       plot.margin = margin(1, 1, 1, 1, unit = "cm"),  # Adjust plot margins
                       panel.grid.major.x = element_blank(), # Remove major horizontal grid lines
                       panel.grid.minor.x = element_blank()
) 


################
#Main text figures
################


####Figure 2 ###


#######Figure 2A, Pred 0: Non-empty Content of remarks vs control
forbiddenspeech$anycontent2 <- factor(forbiddenspeech$anycontent, levels = c( "Anycontent","Control"))
table(forbiddenspeech$anycontent)

p0Anycontent <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ anycontent2,
                                id = ~ answerid,
                                estimate = "mm",
))


p0Anycontentshow<-p0Anycontent + 
  conjoint_theme   +
  geom_point(color = "red", size = 3) + # Change point color and thickness
  scale_y_discrete(labels=c("Any treatment  \n (speech controversy)","Control \n (No speech controversy)","(Content)"))

p0Anycontentshow

ggsave(plot= p0Anycontentshow,"Figure2APredic0Anycontent.png",device=png)

#Fig 2B, Party
data_wouldb <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==1), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==3), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")


####leaners
data_wouldb$group <- "Democrat"
data_woulda$group <- "Republican"

combined_data <- bind_rows(data_wouldb, data_woulda)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Any treatment  \n (speech controversy)","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAnyContentParty<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  scale_color_manual(values = c("Democrat" = "blue", "Republican" = "red")) +
  labs(title = " ", y = " ", x = " ", color = "Party")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pAnyContentParty

ggsave(plot= pAnyContentParty,"Fig2BPred0AnyContentParty.png",device=png)


#Fig 2C, Ideology
data_wouldb <- cregg::cj(subset(forbiddenspeech,ideo3==1), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,ideo3==2), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_wouldd <- cregg::cj(subset(forbiddenspeech,ideo3==3), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")


data_wouldb$group <- "Liberal"
data_woulda$group <- "Moderate"
data_wouldd$group <- "Conservative"

combined_data <- bind_rows(data_wouldb, data_woulda,data_wouldd)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Any treatment  \n (speech controversy)","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAnyContentIdeo<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ideology")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pAnyContentIdeo

ggsave(plot= pAnyContentIdeo,"Fig2CPred0AnyContentIdeo.png",device=png)


###Figure 2D Race
data_wouldb <- cregg::cj(subset(forbiddenspeech,race==2), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,race==1), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_wouldc <- cregg::cj(subset(forbiddenspeech,race==4), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_wouldd <- cregg::cj(subset(forbiddenspeech,race==3), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")


data_wouldb$group <- "Black"
data_woulda$group <- "White"
data_wouldc$group <- "Asian"
data_wouldd$group <- "Hispanic"

combined_data <- bind_rows(data_wouldb, data_woulda,data_wouldc,data_wouldd)
combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Any treatment  \n (speech controversy)","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAnyContentRace<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ethnicity")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pAnyContentRace

ggsave(plot= pAnyContentRace,"Fig2DPred0AnyContentRace.png",device=png)

##Figure 2E, By Gender Pred.0
data_wouldb <- cregg::cj(subset(forbiddenspeech,gender==1), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,gender==2), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")

data_wouldb$group <- "Male"
data_woulda$group <- "Female"
combined_data <- bind_rows(data_wouldb, data_woulda)


combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Any treatment  \n (speech controversy)","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAnyContentGender<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Gender")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pAnyContentGender

ggsave(plot= pAnyContentGender,"Fig2EPred0AnyContentGender.png",device=png)


#Fig 2F, Age, pred.0
data_wouldb <- cregg::cj(subset(forbiddenspeech,birthyr>1980), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,birthyr<1964), wouldconsidernotvoting~ anycontent2, id = ~ respid, estimate = "mm")


data_wouldb$group <- "Millennial or younger"
data_woulda$group <- "Older"


combined_data <- bind_rows(data_wouldb, data_woulda)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Any treatment  \n (speech controversy)","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAnyContentAge<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Age")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pAnyContentAge

ggsave(plot= pAnyContentAge,"Fig2FPred0AnyContentAge.png",device=png)

####################
####Figure 3##########
####################

####Figure 3A, Pred. 1a
forbiddenspeech$content <- factor(forbiddenspeech$nature_severity, levels = c("Slur",  "Dehumanizing", "Stereotype","Denial", "Control" ))
table(forbiddenspeech$content)

pContent <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ content,
                            id = ~ answerid,
                            estimate = "mm",
))


##With boldness
pred1a <- pContent + 
  conjoint_theme +
  geom_point(color = "red", size = 3) +  # Change point color and thickness
  scale_y_discrete(labels = c(
    expression(bold("Slur")),
    expression(bold("Dehumanizing")),
    expression(bold("Stereotype")),
    expression(bold("Denial")),
    "Control \n (No speech controversy)",
    "(Content)"
  )) +
  theme(axis.text.y = element_text(face = "bold")) # Ensures y-axis labels are bold

pred1a

ggsave(plot= pred1a,"Fig3APred1aContent.png",device=png)


###Fig. 3B, Pred 1b: Congruence target and respondent
forbiddenspeech$faccong_responstarget <- factor(forbiddenspeech$cong_responstarget, levels = c("1", "0"))
table(forbiddenspeech$faccong_responstarget)

pCongruence <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ faccong_responstarget,
                               id = ~ answerid,
                               estimate = "mm",
))


pred1b<-pCongruence +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c(expression(bold("Congruent")),"Incongruent","(Congruence \n target-respondent)"))
pred1b

ggsave(plot= pred1b,"Fig3BPred1Congtgt.png",device=png)


###Fig. 3C, Pred 2: Response: Excuses vs other
forbiddenspeech$facresponse <- factor(forbiddenspeech$response_simple, levels = c("Excuse","Defense","Apology","Nocomment",NA))

pDem_Response <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ facresponse,
                                 id = ~ answerid,
                                 estimate = "mm",
),
) 

pred2 <-pDem_Response + conjoint_theme+
  geom_point(color = "red", size = 3) + # Change point color and thickness
  scale_y_discrete(labels=c(expression(bold("Excuse")),"Defense",expression(bold("Apology")),"No comment","(Response)"))
pred2    
ggsave(plot= pred2,"Fig3CPred2Excuses.png",device=png)


###Fig 3D, Pred 3: Aggravating circumstances
forbiddenspeech$agg_circum <- factor(forbiddenspeech$agg_circum, levels = c("3", "2","1","0"))


pDem_Circumstances <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ agg_circum,
                                      id = ~ answerid,
                                      estimate = "mm",
), 
)

pred3Main <-pDem_Circumstances + conjoint_theme +
  geom_point(color = "red", size = 3)  +
  scale_y_discrete(labels=c( expression(bold("Max aggravating \n circumst. (3)")),expression(bold("2")),"1","No aggravating \n circumst. (0)","(Aggravating \n circumstances)"))
pred3Main

ggsave(plot= pred3Main,"Fig3DPred3Main.png",device=png)


###Fig. 3E, Pred 4: Politician’s background traits (in- congruence with respondent)
forbiddenspeech$faccong_responscandidate <- factor(forbiddenspeech$cong_responscandidate, levels = c("0","1"))


pCongpoliticians <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ faccong_responscandidate,
                                    id = ~ answerid,
                                    estimate = "mm",
),
) 

pred4.2<-pCongpoliticians + conjoint_theme +
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c( "All incongruent \n factors","Some congruent \n factor","(Incongruence  \n candidate-respondent)"))

pred4.2
ggsave(plot= pred4.2,"Fig3EPred42Polincongruence.png",device=png)


#####################
#######Appendix Figures
#####################

####################
#####Figure A.2 AMCEs
####################
####Code different variables
forbiddenspeech<- forbiddenspeech %>%
  mutate(women = case_when(
    gender == 2~ 1,
    TRUE~ 0),
    nonwhite= case_when(
      race == 1~ 0,
      TRUE~ 1),
    ageest=2024-birthyr,
    collegegrad= case_when(
      educ4>2 ~ 1,
      TRUE~ 0),
    demlean= case_when( 
      pid7<4 ~1,#democrat or leans democrat
      TRUE ~0) )




######Plot of variously weighted effects AMCE
forbiddenspeech<- forbiddenspeech %>% mutate(incong_responscandidate= case_when(cong_responscandidate==0~ 1,
                                                                    cong_responscandidate==1~ 0))

#Refactor to change Control to be the reference category
forbiddenspeech$nature_severity <- factor(forbiddenspeech$nature_severity, 
                                          levels = c("Control","Denial", "Stereotype", "Dehumanizing", "Slur"))

forbiddenspeech$nature_severity <- relevel(as.factor(forbiddenspeech$nature_severity), ref = "Control")

#aggcircm and response_simple2 that reduce the sample as they are undefined for the pure control group (they didn't receive that question)
#So we aggregate the missing and the control to No comment
forbiddenspeech<- forbiddenspeech %>% mutate(response_simple2= case_when(response_simple=="Control"~ "Nocomment",
                                                                         is.na(response_simple)~ "Nocomment",
                                                                                TRUE~ response_simple))
table(forbiddenspeech$response_simple2)

#Refactor to change Control to be the reference category, and shift order
forbiddenspeech$response_simple2 <- factor(forbiddenspeech$response_simple2, 
                                           levels = c("Defense", "Apology", "Excuse","Nocomment"))

forbiddenspeech$response_simple2 <- relevel(as.factor(forbiddenspeech$response_simple2), ref = "Nocomment")


forbiddenspeech <- forbiddenspeech %>%
  mutate(agg_circum.num = as.numeric(as.character(agg_circum)),
         agg_circum2 = case_when(is.na(agg_circum.num) ~ 0,
                                TRUE ~ agg_circum.num))

forbiddenspeech$agg_circum <- factor(forbiddenspeech$agg_circum, levels = c("3", "2","1","0"))

###Figure A2, Average marginal component effects (AMCEs) for each prediction
Maineffects<-lm(wouldconsidernotvoting ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate,data=forbiddenspeech)

Maineffects.Covs<-lm(wouldconsidernotvoting ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate +women+nonwhite+ageest+collegegrad+demlean+demlean+factor(res_region)+faminc_new,data=forbiddenspeech)
excluded_terms <- c("women", "nonwhite", "ageest", "collegegrad", "demlean",
                    "factor(res_region)2", "factor(res_region)3","factor(res_region)4", "faminc_new")


plotMainRaw<-coefplot::coefplot(Maineffects.Covs,xlim=c(-.1,.1),decreasing=TRUE,color="darkblue",intercept=FALSE,title="", outerCI=2.58, innerCI= 1.96,plot=TRUE,xlab="",ylab="")+theme_bw()+
  theme(axis.text.y = element_text(size = 16)) +  # Increase coefficient label size
  geom_hline(yintercept=c(1.5,2.5,5.5,6.5), linetype=6, color="grey")


plotMainRaw$data <- plotMainRaw$data %>% filter(!(Coefficient %in% excluded_terms))


plotMain<-plotMainRaw+ 
  scale_y_discrete(labels=c( "Incongruence \n candidate-respondent","Aggravating \n circumstances", "Excuse","Apology",  "Defense", "Congruence \n target-respond.", "Slur","Dehumanizing","Stereotype","Denial"   ))

print(plotMain)
ggsave(plot= plotMain,"FigA2MaineffectsNoweight.png",device=png)

#############################
###Figure A.3 (thermometer, objectionable) 
#############################
#Refactor to change Control to be the reference category
forbiddenspeech$nature_severity <- factor(forbiddenspeech$nature_severity, 
                                          levels = c("Control","Denial", "Stereotype", "Dehumanizing", "Slur"))


#Refactor to change Control to be the reference category, and shift order
forbiddenspeech$nature_severity <- relevel(as.factor(forbiddenspeech$nature_severity), ref = "Control")

forbiddenspeech$response_simple2 <- factor(forbiddenspeech$response_simple2, 
                                           levels = c("Defense", "Apology", "Excuse","Nocomment"))

forbiddenspeech$response_simple2 <- relevel(as.factor(forbiddenspeech$response_simple2), ref = "Nocomment")


forbiddenspeech <- forbiddenspeech %>%
  mutate(agg_circum = as.numeric(as.character(agg_circum)),  # convert factor to numeric
         agg_circum2 = case_when(is.na(agg_circum) ~ 0,
                                 TRUE ~ agg_circum))


####AMCE plot these new variables. Note the need to use response_simple2 
Main.thermometer.Covs<-lm(FAVOR_therm ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate+collegegrad+demlean+factor(res_region)+faminc_new, data=forbiddenspeech)
Main.objectionable.Covs<-lm(cand_draw ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate+women+nonwhite+ageest+collegegrad+demlean+factor(res_region)+faminc_new, data=forbiddenspeech)

#Plot A Thermometer
excluded_terms <- c("women", "nonwhite", "ageest", "collegegrad", "demlean",
                    "factor(res_region)2", "factor(res_region)3","factor(res_region)4", "faminc_new")


  
  
  plot.Main.thermometerRaw<-coefplot::coefplot(Main.thermometer.Covs,xlim=c(-.1,.1),decreasing=TRUE,color="red",intercept=FALSE,title="", outerCI=2.58, innerCI= 1.96,plot=TRUE,xlab="",ylab="")+theme_bw()+
  geom_hline(yintercept=c(1.5,2.5,5.5,6.5), linetype=6, color="grey") +
    theme(axis.text.y = element_text(size = 16))   # Increase coefficient label size

plot.Main.thermometerRaw$data <- plot.Main.thermometerRaw$data %>% filter(!(Coefficient %in% excluded_terms))

plot.Main.thermometerRawShow<- plot.Main.thermometerRaw+  scale_y_discrete(labels=c( "Incongruence \n candidate-respondent","Aggravating \n circumstances", "Excuse","Apology",  "Defense", "Congruence \n target-respond.",  "Slur", "Dehumanizing", "Stereotype","Denial")) + theme(axis.text.y = element_text(size = 12))
plot.Main.thermometerRawShow

ggsave(plot= plot.Main.thermometerRawShow,"FigA3AMainThermometer.png",device=png, height = 386, width = 414, units = "mm")


#Plot B Objectionable
plot.Main.objectionableRaw<-coefplot::coefplot(Main.objectionable.Covs,xlim=c(-.1,.1),decreasing=TRUE,color="darkgray",intercept=FALSE,title="", outerCI=2.98, innerCI= 2.5,plot=TRUE,xlab="",ylab="")+theme_bw()+ theme(axis.text.y = element_text(size = 12))
  geom_hline(yintercept=c(1.5,2.5,5.5,6.5), linetype=6, color="grey") 

plot.Main.objectionableRaw$data <- plot.Main.objectionableRaw$data %>% filter(!(Coefficient %in% excluded_terms))

plot.Main.objectionableRawShow<- plot.Main.objectionableRaw+  scale_y_discrete(labels=c( "Incongruence \n candidate-respondent","Aggravating \n circumstances", "Excuse","Apology",  "Defense", "Congruence \n target-respond.",  "Slur", "Dehumanizing", "Stereotype","Denial")) 
plot.Main.objectionableRawShow

ggsave(plot= plot.Main.objectionableRawShow,"FigA3BMainObjectionable.png",device=png, height = 386, width = 414, units = "mm")



#############################
####Figure A.4, Party subgroups
#############################

###Pred 1a: Content of remarks
#altering order
data_wouldb <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==1), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==3), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")

data_wouldb$group <- "Democrat"
data_woulda$group <- "Republican"

combined_data <- bind_rows(data_wouldb, data_woulda)


combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Slur","Dehumanizing","Stereotype","Denial","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pContentParty<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  scale_color_manual(values = c("Democrat" = "blue", "Republican" = "red")) +
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Party")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pContentParty

ggsave(plot= pContentParty,"FigA4APred1aContentParty.png",device=png)




###Pred 1b: Congruence target and respondent
#Overall, some congruence
data_congb <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==1), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_conga <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==3), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")

data_congb$group <- "Democrat"
data_conga$group <- "Republican"

combined_data <- bind_rows(data_congb, data_conga)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongruentParty<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  scale_color_manual(values = c("Democrat" = "blue", "Republican" = "red")) +
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Party")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pCongruentParty

ggsave(plot= pCongruentParty,"FigA4Pred1bCongruentParty.png",device=png)


###Pred 2: Response: Excuses vs other
data_respb <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==1),wouldconsidernotvoting~ facresponse,id = ~ respid,estimate = "mm") 
data_respa <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==3),wouldconsidernotvoting~ facresponse,id = ~ respid,estimate = "mm")

data_respb$group <- "Democrat"
data_respa$group <- "Republican"

combined_data <- bind_rows(data_respb, data_respa)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) + scale_color_manual(values = c("Democrat" = "blue", "Republican" = "red")) +
  plot_theme +
  scale_x_discrete(labels=c("Excuse","Apology","Defense","No comment","(Response)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pResponseParty<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Party")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pResponseParty

ggsave(plot= pResponseParty,"FigA4CPredResponseParty.png",device=png)

###Pred 3: Aggravating circumstances
forbiddenspeech$agg_circum <- factor(forbiddenspeech$agg_circum, levels = c("3", "2","1","0"))
data_aggcircb <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==1),wouldconsidernotvoting~ agg_circum,id = ~ respid,estimate = "mm") 
data_aggcirca <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==3),wouldconsidernotvoting~ agg_circum,id = ~ respid,estimate = "mm") 

data_aggcircb$group <- "Democrat"
data_aggcirca$group <- "Republican"

combined_data <- bind_rows(data_aggcircb, data_aggcirca)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "Max aggravating \n circumst. (3)","2","1","No aggravating \n circumst. (0)","(Aggravating \n circumstances)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAggcircParty<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +  scale_color_manual(values = c("Democrat" = "blue", "Republican" = "red")) +
  labs(title = " ", y = " ", x = " ", color = "Party")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pAggcircParty

ggsave(plot= pAggcircParty,"FigA4DPredAggcircParty.png",device=png)


###Pred 4: Incongruence politician respondent traits
data_congrespb <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==1), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespa <- cregg::cj(subset(forbiddenspeech,pid7_with_leaners==3), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")

data_congrespb$group <- "Democrat"
data_congrespa$group <- "Republican"

combined_data <- bind_rows(data_congrespb, data_congrespa)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "All incongruent \n factors","Some congruent \n factor","(Incongruence  \n candidate-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongrespParty<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +  scale_color_manual(values = c("Democrat" = "blue", "Republican" = "red")) +
  labs(title = " ", y = " ", x = " ", color = "Party")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pCongrespParty

ggsave(plot= pCongrespParty,"FigA4EPredCongrespParty.png",device=png)

############
######Figure A.5: By ideology subgroups
############

###Pred 1a: Content of remarks
data_wouldb <- cregg::cj(subset(forbiddenspeech,ideo3==1), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,ideo3==2), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_wouldd <- cregg::cj(subset(forbiddenspeech,ideo3==3), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")


data_wouldb$group <- "Liberal"
data_woulda$group <- "Moderate"
data_wouldd$group <- "Conservative"

combined_data <- bind_rows(data_wouldb, data_woulda,data_wouldd)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Slur","Dehumanizing","Stereotype","Denial","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pContentIdeo<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ideology")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pContentIdeo

ggsave(plot= pContentIdeo,"FigA5APred1apContentIdeo.png",device=png)



###Pred 1b: Congruence target and respondent
data_congb <- cregg::cj(subset(forbiddenspeech,ideo3==1), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_conga <- cregg::cj(subset(forbiddenspeech,ideo3==2), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_congd <- cregg::cj(subset(forbiddenspeech,ideo3==3), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")

data_congb$group <- "Liberal"
data_conga$group <- "Moderate"
data_congd$group <- "Conservative"

combined_data <- bind_rows(data_congb, data_conga,data_congd)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pCongruentIdeo<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ideology")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pCongruentIdeo

ggsave(plot= pCongruentIdeo,"FigA5BPred1bCongruentIdeo.png",device=png)


###Pred 2: Response: Excuses vs other
data_respb <- cregg::cj(subset(forbiddenspeech,ideo3==1), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respa <- cregg::cj(subset(forbiddenspeech,ideo3==2), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respd <- cregg::cj(subset(forbiddenspeech,ideo3==3), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")

data_respb$group <- "Liberal"
data_respa$group <- "Moderate"
data_respd$group <- "Conservative"

combined_data <- bind_rows(data_respb, data_respa,data_respd)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Excuse","Apology","Defense","No comment","(Response)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pResponseIdeo<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ideology")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pResponseIdeo

ggsave(plot= pResponseIdeo,"FigA5CpResponseIdeo.png",device=png)

###Pred 3: Aggravating circumstances
data_aggcircb <- cregg::cj(subset(forbiddenspeech,ideo3==1), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcirca <- cregg::cj(subset(forbiddenspeech,ideo3==2), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcircd <- cregg::cj(subset(forbiddenspeech,ideo3==3), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")

data_aggcircb$group <- "Liberal"
data_aggcirca$group <- "Moderate"
data_aggcircd$group <- "Conservative"



combined_data <- bind_rows(data_aggcircb, data_aggcirca,data_aggcircd)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "Max aggravating \n circumst. (3)","2","1","No aggravating \n circumst. (0)","(Aggravating \n circumstances)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAggcircIdeo<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ideology")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pAggcircIdeo

ggsave(plot= pAggcircIdeo,"FigA5DpAggcircIdeo.png",device=png)


###Pred 4: Incongruence politician respondent traits
data_congrespb <- cregg::cj(subset(forbiddenspeech,ideo3==1), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespa <- cregg::cj(subset(forbiddenspeech,ideo3==2), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespd <- cregg::cj(subset(forbiddenspeech,ideo3==3), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")


data_congrespb$group <- "Liberal"
data_congrespa$group <- "Moderate"
data_congrespd$group <- "Conservative"

combined_data <- bind_rows(data_congrespb, data_congrespa,data_congrespd)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "All incongruent \n factors","Some congruent \n factor","(Incongruence  \n candidate-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongrespIdeo<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ideology")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pCongrespIdeo

ggsave(plot= pCongrespIdeo,"FigA5DpCongrespIdeo.png",device=png)

#########
#########Figure A.6: By race subgroups
#########

###Pred 1a: Content of remarks
data_wouldb <- cregg::cj(subset(forbiddenspeech,race==2), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,race==1), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_wouldc <- cregg::cj(subset(forbiddenspeech,race==4), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_wouldd <- cregg::cj(subset(forbiddenspeech,race==3), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")


data_wouldb$group <- "Black"
data_woulda$group <- "White"
data_wouldc$group <- "Asian"
data_wouldd$group <- "Hispanic"

combined_data <- bind_rows(data_wouldb, data_woulda,data_wouldc,data_wouldd)


combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Slur","Dehumanizing","Stereotype","Denial","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pContentRace<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ethnicity")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pContentRace

ggsave(plot= pContentRace,"FigA6APred1apContentRace.png",device=png)



###Pred 1b: Congruence target and respondent
data_congb <- cregg::cj(subset(forbiddenspeech,race==2), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_conga <- cregg::cj(subset(forbiddenspeech,race==1), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_congc <- cregg::cj(subset(forbiddenspeech,race==4), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_congd <- cregg::cj(subset(forbiddenspeech,race==3), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")


data_congb$group <- "Black"
data_conga$group <- "White"
data_congc$group <- "Asian"
data_congd$group <- "Hispanic"


combined_data <- bind_rows(data_congb, data_conga,data_congc,data_congd)


combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pCongruentRace<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ethnicity")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pCongruentRace

ggsave(plot= pCongruentRace,"FigA6BPred1bCongruentRace.png",device=png)


###Pred 2: Response: Excuses vs other
data_respb <- cregg::cj(subset(forbiddenspeech,race==2), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respa <- cregg::cj(subset(forbiddenspeech,race==1), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respc <- cregg::cj(subset(forbiddenspeech,race==4), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respd <- cregg::cj(subset(forbiddenspeech,race==3), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")


data_respb$group <- "Black"
data_respa$group <- "White"
data_respc$group <- "Asian"
data_respd$group <- "Hispanic"


combined_data <- bind_rows(data_respb, data_respa,data_respd,data_respc)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Excuse","Apology","Defense","No comment","(Response)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pResponseRace<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ethnicity")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pResponseRace

ggsave(plot= pResponseRace,"FigA6CpResponseRace.png",device=png)



###Pred 3: Aggravating circumstances
data_aggcircb <- cregg::cj(subset(forbiddenspeech,race==2), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcirca <- cregg::cj(subset(forbiddenspeech,race==1), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcircc <- cregg::cj(subset(forbiddenspeech,race==4), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcircd <- cregg::cj(subset(forbiddenspeech,race==3), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")

data_aggcircb$group <- "Black"
data_aggcirca$group <- "White"
data_aggcircc$group <- "Asian"
data_aggcircd$group <- "Hispanic"


combined_data <- bind_rows(data_aggcircb, data_aggcirca,data_aggcircd,data_aggcircc)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "Max aggravating \n circumst. (3)","2","1","No aggravating \n circumst. (0)","(Aggravating \n circumstances)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAggcircRace<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ethnicity")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pAggcircRace

ggsave(plot= pAggcircRace,"FigA6DpAggcircRace.png",device=png)


###Pred 4: Incongruence politician respondent traits
data_congrespb <- cregg::cj(subset(forbiddenspeech,race==2), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespa <- cregg::cj(subset(forbiddenspeech,race==1), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespc <- cregg::cj(subset(forbiddenspeech,race==4), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespd <- cregg::cj(subset(forbiddenspeech,race==3), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")


data_congrespb$group <- "Black"
data_congrespa$group <- "White"
data_congrespc$group <- "Asian"
data_congrespd$group <- "Hispanic"

combined_data <- bind_rows(data_congrespb, data_congrespa,data_congrespd,data_congrespc)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "All incongruent \n factors","Some congruent \n factor","(Incongruence  \n candidate-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongrespRace<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Ethnicity")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pCongrespRace

ggsave(plot= pCongrespRace,"FigA6EpCongrespRace.png",device=png)

##################
######Figure A7: By gender subgroups
##################

###Pred 1a: Content of remarks
data_wouldb <- cregg::cj(subset(forbiddenspeech,gender==1), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,gender==2), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")

data_wouldb$group <- "Male"
data_woulda$group <- "Female"

combined_data <- bind_rows(data_wouldb, data_woulda)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Slur","Dehumanizing","Stereotype","Denial","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pContentGender<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Gender")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))

pContentGender

ggsave(plot= pContentGender,"FigA7APred1aContentGender.png",device=png)

###Pred 1b: Congruence target and respondent
data_congb <- cregg::cj(subset(forbiddenspeech,gender==1), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_conga <- cregg::cj(subset(forbiddenspeech,gender==2), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")

data_congb$group <- "Male"
data_conga$group <- "Female"

combined_data <- bind_rows(data_congb, data_conga)


combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongruentGender<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Gender")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pCongruentGender

ggsave(plot= pCongruentGender,"FigA7BPred1bCongruentGender.png",device=png)


###Pred 2: Response: Excuses vs other
data_respb <- cregg::cj(subset(forbiddenspeech,gender==1), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respa <- cregg::cj(subset(forbiddenspeech,gender==2), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")

data_respb$group <- "Male"
data_respa$group <- "Female"

combined_data <- bind_rows(data_respb, data_respa)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Excuse","Apology","Defense","No comment","(Response)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pResponseGender<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Gender")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pResponseGender

ggsave(plot= pResponseGender,"FigA7CPredResponseGender.png",device=png)



###Pred 3: Aggravating circumstances
data_aggcircb <- cregg::cj(subset(forbiddenspeech,gender==1), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcirca <- cregg::cj(subset(forbiddenspeech,gender==2), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")

data_aggcircb$group <- "Male"
data_aggcirca$group <- "Female"

combined_data <- bind_rows(data_aggcircb, data_aggcirca)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "Max aggravating \n circumst. (3)","2","1","No aggravating \n circumst. (0)","(Aggravating \n circumstances)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAggcircGender<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Gender")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pAggcircGender

ggsave(plot= pAggcircGender,"FigA7DPredAggcircGenderGender.png",device=png)


###Pred 4: Incongruence politician respondent traits
data_congrespb <- cregg::cj(subset(forbiddenspeech,gender==1), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespa <- cregg::cj(subset(forbiddenspeech,gender==2), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")

data_congrespb$group <- "Male"
data_congrespa$group <- "Female"

combined_data <- bind_rows(data_congrespb, data_congrespa)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "All incongruent \n factors","Some congruent \n factor","(Incongruence  \n candidate-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongrespGender<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Gender")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))
pCongrespGender

ggsave(plot= pCongrespGender,"FigA7EPredCongrespGender.png",device=png)


##################
######Figure A8, By age subgroups
##################

###Pred 1a: Content of remarks
#altering order
data_wouldb <- cregg::cj(subset(forbiddenspeech,birthyr>1980), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")
data_woulda <- cregg::cj(subset(forbiddenspeech,birthyr<1964), wouldconsidernotvoting~ content, id = ~ respid, estimate = "mm")

data_wouldb$group <- "Millennial or younger"
data_woulda$group <- "Older"


combined_data <- bind_rows(data_wouldb, data_woulda)


combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Slur","Dehumanizing","Stereotype","Denial","Control \n (No speech controversy)","(Content)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pContentAge<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Age")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))

pContentAge

ggsave(plot= pContentAge,"FigA8APred1apContentAge.png",device=png)



###Pred 1b: Congruence target and respondent
data_congb <- cregg::cj(subset(forbiddenspeech,birthyr>1980), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")
data_conga <- cregg::cj(subset(forbiddenspeech,birthyr<1964), wouldconsidernotvoting~ faccong_responstarget, id = ~ respid, estimate = "mm")

data_congb$group <- "Millennial or younger"
data_conga$group <- "Older"

combined_data <- bind_rows(data_congb, data_conga)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pCongruentAge<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Age")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pCongruentAge

ggsave(plot= pCongruentAge,"FigA8BPred1bCongruentAge.png",device=png)



###Pred 2: Response: Excuses vs other
data_respb <- cregg::cj(subset(forbiddenspeech,birthyr>1980), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")
data_respa <- cregg::cj(subset(forbiddenspeech,birthyr<1964), wouldconsidernotvoting~ facresponse, id = ~ respid, estimate = "mm")

data_respb$group <- "Millennial or younger"
data_respa$group <-  "Older"


combined_data <- bind_rows(data_respb, data_respa)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c("Excuse","Apology","Defense","No comment","(Response)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pResponseAge<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Age")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pResponseAge

ggsave(plot= pResponseAge,"FigA8CpResponseAge.png",device=png)



###Pred 3: Aggravating circumstances
data_aggcircb <- cregg::cj(subset(forbiddenspeech,birthyr>1980), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")
data_aggcirca <- cregg::cj(subset(forbiddenspeech,birthyr<1964), wouldconsidernotvoting~ agg_circum, id = ~ respid, estimate = "mm")

data_aggcircb$group <- "Millennial or younger"
data_aggcirca$group <- "Older"

combined_data <- bind_rows(data_aggcircb, data_aggcirca)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "Max aggravating \n circumst. (3)","2","1","No aggravating \n circumst. (0)","(Aggravating \n circumstances)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 


pAggcircAge<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Age")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pAggcircAge

ggsave(plot= pAggcircAge,"FigA8DpAggcircAge.png",device=png)


###Pred 4: Incongruence politician respondent traits
data_congrespb <- cregg::cj(subset(forbiddenspeech,birthyr>1980), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")
data_congrespa <- cregg::cj(subset(forbiddenspeech,birthyr<1964), wouldconsidernotvoting~ faccong_responscandidate, id = ~ respid, estimate = "mm")

data_congrespb$group <- "Millennial or younger"
data_congrespa$group <- "Older"


combined_data <- bind_rows(data_congrespb, data_congrespa)

combined_plot <- ggplot(combined_data, aes(x = level, y = estimate, color = group)) +
  geom_point(position = position_dodge(width = 0.5)) +
  scale_x_discrete(labels=c( "All incongruent \n factors","Some congruent \n factor","(Incongruence  \n candidate-respondent)"))+
  theme_minimal() +  coord_flip()

combined_plotse<- combined_plot + geom_errorbar(aes(ymin = lower, ymax = upper), width = 0, position = position_dodge(width = 0.5)) 

pCongrespAge<- combined_plotse   +
  scale_y_continuous(limits = c(0, 1), expand = c(0, 0))+
  plot_theme +
  labs(title = " ", y = " ", x = " ", color = "Age")+
  theme(legend.position="bottom",panel.border = element_rect(colour = "black", fill = NA, size = 1))+
  guides(color = guide_legend(nrow = 2))
pCongrespAge

ggsave(plot= pCongrespAge,"FigA8EpCongrespAge.png",device=png)


###Figure A.9  Marginal means (MMs) of the probability of answering “I would NEVER consider voting for this candidate” by type of target-respondent congruence
#Figure A.9, A Race
forbiddenspeech$congrace_respontarget <- factor(forbiddenspeech$congrace_respontarget, levels = c("1", "0"))

pRaceCongruence <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ congrace_respontarget,
                                   id = ~ respid,
                                   estimate = "mm",
))

pRaceCongruence

predRaceCongtarget<-pRaceCongruence +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))
predRaceCongtarget

ggsave(plot= predRaceCongtarget,"FigA9ApredRaceCongtarget.png",device=png)

#Figure A.9, B Religion
forbiddenspeech$congreligion_respontarget <- factor(forbiddenspeech$congreligion_respontarget, levels = c("1", "0"))

pReligionCongruence <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ congreligion_respontarget,
                                       id = ~ respid,
                                       estimate = "mm",
))

pReligionCongruence

predReligionCongtarget<-pReligionCongruence +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))
predReligionCongtarget

ggsave(plot= predReligionCongtarget,"FigA9BpredReligionCongtarget.png",device=png)


#Figure A.9, C Sexual orientation
forbiddenspeech$congsexorientation_respontarget <- factor(forbiddenspeech$congsexorientation_respontarget, levels = c("1", "0"))


pSexOrientationCongruence <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ congsexorientation_respontarget,
                                             id = ~ respid,
                                             estimate = "mm",
))

pSexOrientationCongruence

predSexOrientationCongtarget<-pSexOrientationCongruence +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))
predReligionCongtarget

ggsave(plot= predSexOrientationCongtarget,"FigA9CpredSexOrientationCongtarget.png",device=png)

#Figure A.9, D Gender
forbiddenspeech$conggender_responstarget <- factor(forbiddenspeech$conggender_responstarget, levels = c("1", "0"))

pGenderCongruence <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ conggender_responstarget,
                                     id = ~ respid,
                                     estimate = "mm",
))

preGenderCongtarget<-pGenderCongruence +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Congruent","Incongruent","(Congruence \n target-respondent)"))
predReligionCongtarget

ggsave(plot= preGenderCongtarget,"FigA9DpreGenderCongtarget.png",device=png)


#Figure A.10: AMCEs for different type of aggravating factor
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    recent = case_when(
      fiveyears==1 ~ 0,
      fiveyears==0 ~ 1,
      TRUE ~ NA
    )
  )   

Recent<-lm(wouldconsidernotvoting ~ recent,data=forbiddenspeech)
Planned<-lm(wouldconsidernotvoting ~ facplanned,data=forbiddenspeech)
Made.comment.before<-lm(wouldconsidernotvoting ~ frequent,data=forbiddenspeech)


plotCombined<-coefplot::multiplot(Recent,Planned,Made.comment.before,decreasing=TRUE,title="", outerCI=2.58, innerCI= 1.96,plot=TRUE,xlab="",ylab="",intercept=FALSE) +theme_bw()+
  scale_y_discrete(labels=c("", "Aggravating \n circumstance",""))
plotCombined
ggsave(plot= plotCombined,"FigA10Combinedeffects.png",device=png)


###Figure A.11 Marginal means (MMs) of the probability of answering “I would NEVER consider voting for this candidate” by type of respondent-politician incongruence
#Types of incongruence respondent and politician
#Figure A11, A, Party
pInCongruencePartyRespCandidate <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ incongparty_responscandidate,
                                            id = ~ respid,
                                            estimate = "mm",
))

predInCongruencePartyRespCandidate<-pInCongruencePartyRespCandidate +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Incongruent","Congruent","(Party incongruence \n candidate-respondent)"))
predInCongruencePartyRespCandidate

ggsave(plot= predInCongruencePartyRespCandidate,"FigA11ApredInCongruencePartyRespCandidate.png",device=png)


#Figure A11, B, Race
pInCongruenceRaceRespCandidate <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ incongrace_responscandidate,
                                                   id = ~ respid,
                                                   estimate = "mm",
))

predInCongruenceRaceRespCandidate<-pInCongruenceRaceRespCandidate +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Incongruent","Congruent","(Race incongruence \n candidate-respondent)"))
predInCongruenceRaceRespCandidate

ggsave(plot= predInCongruenceRaceRespCandidate,"FigA11BpredInCongruenceRaceRespCandidate.png",device=png)

#Figure A11, C, Gender
pInCongruenceGenderRespCandidate <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ inconggender_responscandidate,
                                                  id = ~ respid,
                                                  estimate = "mm",
))

predInCongruenceGenderRespCandidate<-pInCongruenceGenderRespCandidate +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Incongruent","Congruent","(Gender incongruence \n candidate-respondent)"))
predInCongruenceGenderRespCandidate

ggsave(plot= predInCongruenceGenderRespCandidate,"FigA11CpredInCongruenceGenderRespCandidate.png",device=png)


#Figure A11, D, Age
pInCongruenceAgeRespCandidate <- plot( cregg::cj(forbiddenspeech,wouldconsidernotvoting~ incongage_responscandidate,
                                                    id = ~ respid,
                                                    estimate = "mm",
))

predInCongruenceAgeRespCandidate<-pInCongruenceAgeRespCandidate +   conjoint_theme + 
  geom_point(color = "red", size = 3) +
  scale_y_discrete(labels=c("Incongruent","Congruent","(Age incongruence \n candidate-respondent)"))
predInCongruenceAgeRespCandidate

ggsave(plot= predInCongruenceAgeRespCandidate,"FigA11DpredInCongruenceAgeRespCandidate.png",device=png)


###############
###Figure A.12: Average marginal component effects (AMCEs) for each prediction under different scenarios
###############

#Fig A12, A
#Weighted effects, observed weights state legislature
#weighting each observation by presence in state legislatures nationwide
#https://docs.google.com/spreadsheets/d/10jVYxw53IMqnnm-JJcMv4Y-wlhN17MfWBHz8hGKljJs/edit#gid=0

forbiddenspeech <- forbiddenspeech %>%
  mutate(
    statelegisl_weight = case_when(
      white_pol==0 & man_pol==0 & millennial_pol==0 ~ 0.5532216196,
      white_pol==0 & man_pol==1 & millennial_pol==0 ~ 1.326885494,
      white_pol==0 & man_pol==0 & millennial_pol==1 ~ 0.03529874376,
      white_pol==0 & man_pol==1 & millennial_pol==1 ~ 0.08466298022,
      white_pol==1 & man_pol==0 & millennial_pol==0 ~ 1.659588697,
      white_pol==1 & man_pol==1 & millennial_pol==0 ~ 3.980473809,
      white_pol==1 & man_pol==0 & millennial_pol==1 ~ 0.1058913717,
      white_pol==1 & man_pol==1 & millennial_pol==1 ~ 0.2539772851,
      TRUE ~ 1
    )
  )       

MainStLegweights.Covs<-lm(wouldconsidernotvoting ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2 +incong_responscandidate+women+nonwhite+ageest+collegegrad+demlean+factor(res_region)+faminc_new,data=forbiddenspeech, weights= statelegisl_weight)


plot.new()
plotStLegislRaw<-coefplot::coefplot(MainStLegweights.Covs,xlim=c(-.1,.1),decreasing=TRUE,color="darkblue",intercept=FALSE,title="", outerCI=2.58, innerCI= 1.96,plot=TRUE,xlab="",ylab="")+theme_bw()+
  geom_hline(yintercept=c(1.5,2.5,5.5,6.5), linetype=6, color="grey") +
  theme(axis.text.y = element_text(size = 16))   # Increase coefficient label size

plotStLegislRaw$data <- plotStLegislRaw$data %>% filter(!(Coefficient %in% excluded_terms))

plotStLegisl<-plotStLegislRaw+ 
  scale_y_discrete(labels=c( "Incongruence \n candidate-respondent","Aggravating \n circumstances", "Excuse","Apology",  "Defense", "Congruence \n target-respond.", "Slur","Dehumanizing","Stereotype","Denial"))
plotStLegisl
ggsave(plot= plotStLegisl,"FigA12BMaineffectsStLegisl.png",device=png)


###Figure A12, B Observations weighted for “low expected of state legislators rule out” scenario
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    mild_weight = case_when(
      nature_severity=="Denial" ~ 2,
      frequent==0~ 2,
      facplanned==0~ 2,
      response_simple=="Apology"~ 2,
      fiveyears==1~ 2,
      TRUE ~ 1
    )
  )

MainMildcases.Covs<-lm(wouldconsidernotvoting ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate+women+nonwhite+ageest+collegegrad+demlean+factor(res_region)+faminc_new,data=forbiddenspeech, weights= mild_weight)

plot.new()
plotMildcasesRaw<-coefplot::coefplot(MainMildcases.Covs,xlim=c(-.1,.1),decreasing=TRUE,color="darkblue",intercept=FALSE,title="", outerCI=2.58, innerCI= 1.96,plot=TRUE,xlab="",ylab="")+theme_bw()+
  geom_hline(yintercept=c(1.5,2.5,5.5,6.5), linetype=6, color="grey")+
  theme(axis.text.y = element_text(size = 16))   # Increase coefficient label size

plotMildcasesRaw$data <- plotMildcasesRaw$data %>% filter(!(Coefficient %in% excluded_terms))

plotMildcases<-plotMildcasesRaw+ 
  scale_y_discrete(labels=c( "Incongruence \n candidate-respondent","Aggravating \n circumstances", "Excuse","Apology",  "Defense", "Congruence \n target-respond.", "Slur","Dehumanizing","Stereotype","Denial"))
plotMildcases

ggsave(plot= plotMildcases,"FigA12BMaineffectsMildcases.png",device=png)


#Fig A12, C Observations weighted for “high expected rule out” scenario (Egregious cases)
forbiddenspeech <- forbiddenspeech %>%
  mutate(
    egregious_weight = case_when(
      nature_severity=="Slur" ~ 2,
      frequent==1~ 2,
      facplanned==1~ 2,
      response_simple=="Defense"~ 2,
      fiveyears==0~ 2,
      TRUE ~ 1
    )
  )   

MainEgregcases.Covs<-lm(wouldconsidernotvoting ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate+women+nonwhite+ageest+collegegrad+demlean+factor(res_region)+faminc_new,data=forbiddenspeech,  weights= egregious_weight)
summary(MainEgregcases.Covs)


plot.new()
PlotMainEgregcasesRaw<-coefplot::coefplot(MainEgregcases.Covs,xlim=c(-.1,.1),decreasing=TRUE,color="darkblue",intercept=FALSE,title="", outerCI=2.58, innerCI= 1.96,plot=TRUE,xlab="",ylab="")+theme_bw()+
  geom_hline(yintercept=c(1.5,2.5,5.5,6.5), linetype=6, color="grey")+
  theme(axis.text.y = element_text(size = 16))   # Increase coefficient label size

PlotMainEgregcasesRaw$data <- PlotMainEgregcasesRaw$data %>% filter(!(Coefficient %in% excluded_terms))

PlotMainEgregcases <-PlotMainEgregcasesRaw + 
  scale_y_discrete(labels=c( "Incongruence \n candidate-respondent","Aggravating \n circumstances", "Excuse","Apology",  "Defense", "Congruence \n target-respond.", "Slur","Dehumanizing","Stereotype","Denial"))
PlotMainEgregcases
ggsave(plot= PlotMainEgregcases,"FigA12CMaineffectsEgregiouscases.png",device=png)


##################
### Figure A.13: AMCEs for alternative variables within each composite
################## 

## Figure A.13.A: Nature of original remarks (severity)
#Creating a composite variable as follows
forbiddenspeech <- forbiddenspeech %>%
  mutate(bycomposite = case_when(
    nature_severity == "Control" ~ "Control",
    TRUE ~ paste(nature_severity, nature_targetdetailed, split_treat_quote, sep = "_")
  )
  )

table(forbiddenspeech$bycomposite)

###Model for all of the different composites
# Ensure 'bycomposite' is a factor and set 'Control' as the reference category
forbiddenspeech <- forbiddenspeech %>%
  mutate(bycomposite = relevel(factor(bycomposite), ref = "Control"))

Bycompositeeffects<-lm(wouldconsidernotvoting ~ bycomposite,data=forbiddenspeech)


# Extract coefficient names and clean them up
coef_labels <- names(coef(Bycompositeeffects)) %>% 
  str_replace_all("bycomposite", "") %>%  # Remove "bycomposite"
  str_replace_all("_", " ")  # Optional: Replace underscores with spaces for readability

# Ensure correct ordering and remove intercept
coef_labels <- coef_labels[-1]  # Exclude the intercept

# Generate coefplot
plotComposite <- coefplot(Bycompositeeffects, 
                          title = "", 
                          sort = "alphabetical", 
                          outerCI = 2.58, 
                          innerCI = 1.95, 
                          plot = TRUE, 
                          xlab = "", 
                          ylab = "", 
                          intercept = FALSE) + 
  theme_bw() +
  theme(axis.text.y = element_text(size = 8),  # Reduce font size for better spacing
        plot.title = element_text(size = 10),  
        axis.text.x = element_text(size = 10), 
        axis.title.x = element_text(size = 10),
        axis.title.y = element_text(size = 10)) +
  scale_y_discrete(labels = coef_labels) +  # Apply cleaned labels
  geom_hline(yintercept = seq(14.5, length(coef_labels) - 0.5, by=14), 
             linetype = "dashed", color = "grey")

# Print the plot
print(plotComposite)
ggsave(plot= plotComposite,"FigA13AplotComposite.png",device=png)


### Figure A.13.B. Pred. 2: Politician’s response
## Responses by composites

forbiddenspeech <- forbiddenspeech %>%
  mutate(responsecomposite = factor(
    split_treat_response,
    levels = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 99),
    labels = c(
      "Apology_Remorseful", "Apology_Woke", "Apology_Sorry_I_offended",
      "Excuse_Plead_ignorance", "Excuse_Misspoke", "Excuse_Taken_out_of_context",
      "Defense_Deny_wrongdoing", "Defense_Play_the_victim", "Defense_Go_on_the_attack",
      "No_comment", "Control"
    )
  ))


forbiddenspeech <- forbiddenspeech %>%
  mutate(responsecompositequote = case_when(
    is.na(split_treat_response)  ~ "Control",
    TRUE ~ paste(responsecomposite, split_treat_quote, sep = "_")
  )
  )

table(forbiddenspeech$responsecompositequote)


###Model for all of the different composites
# Ensure 'bycomposite' is a factor and set 'Control' as the reference category
forbiddenspeech <- forbiddenspeech %>%
  mutate(responsecompositequote = relevel(factor(responsecompositequote), ref = "Control"))

Byresponsecompsiteeffects<-lm(wouldconsidernotvoting ~ responsecompositequote,data=forbiddenspeech)
summary(Byresponsecompsiteeffects)


# Extract coefficient names and clean them up
coef_labels <- names(coef(Byresponsecompsiteeffects)) %>% 
  str_replace_all("responsecompositequote", "") %>%  # Remove "bycomposite"
  str_replace_all("_", " ")  # Optional: Replace underscores with spaces for readability

# Ensure correct ordering and remove intercept
coef_labels <- coef_labels[-1]  # Exclude the intercept

# Generate coefplot
plotResponseComposite <- coefplot(Byresponsecompsiteeffects, 
                                  title = "", 
                                  sort = "alphabetical", 
                                  outerCI = 2.58, 
                                  innerCI = 1.95, 
                                  plot = TRUE, 
                                  xlab = "", 
                                  ylab = "", 
                                  intercept = FALSE) + 
  theme_bw() +
  theme(axis.text.y = element_text(size = 8),  # Reduce font size for better spacing
        plot.title = element_text(size = 10),  
        axis.text.x = element_text(size = 10), 
        axis.title.x = element_text(size = 10),
        axis.title.y = element_text(size = 10)) +
  scale_y_discrete(labels = coef_labels) +  # Apply cleaned labels
  geom_hline(yintercept = seq(6.5, length(coef_labels) - 0.5, by=6), 
             linetype = "dashed", color = "grey")

# Print the plot
print(plotResponseComposite)


ggsave(plot= plotResponseComposite,"FigA13BplotResponseComposite.png",device=png)





###################
#####Appendix Tables
###################

####Table A5, Balance table, summary statistics 
# Create a new variable with midpoint values
forbiddenspeech$faminc_cont <- with(forbiddenspeech, 
                                    ifelse(faminc_new == 1, 5000,
                                           ifelse(faminc_new == 2, 15000,
                                                  ifelse(faminc_new == 3, 25000,
                                                         ifelse(faminc_new == 4, 35000,
                                                                ifelse(faminc_new == 5, 45000,
                                                                       ifelse(faminc_new == 6, 55000,
                                                                              ifelse(faminc_new == 7, 65000,
                                                                                     ifelse(faminc_new == 8, 75000,
                                                                                            ifelse(faminc_new == 9, 90000,
                                                                                                   ifelse(faminc_new == 10, 110000,
                                                                                                          ifelse(faminc_new == 11, 135000,
                                                                                                                 ifelse(faminc_new == 12, 175000,
                                                                                                                        ifelse(faminc_new == 13, 225000,
                                                                                                                               ifelse(faminc_new == 14, 300000,
                                                                                                                                      ifelse(faminc_new == 15, 425000,
                                                                                                                                             ifelse(faminc_new == 16, 600000,
                                                                                                                                                    NA)))))))))))))))))



#Table A.5: Comparison with USA national values and balance of the covariates across the used sample and reported incompletes

# Create a data frame with means and standard deviations
table_data <- data.frame(
  Variable = c("Female", "Over 65", "White", "Black", "Asian", "Hispanic", 
               "% Democrat or Leans Democrat", "% College graduate", "% Employed", "Income (continuous)"), Estimate = sprintf("%.3f\n(%.3f)", 
                                                                                                                              c(mean(forbiddenspeech$gender == 2, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$age5 >= 5, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$race == 1, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$race == 2, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$race == 4, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$race == 3, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$pid7 < 4, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$educ4>2,na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$employ < 4, na.rm = TRUE),
                                                                                                                                mean(forbiddenspeech$faminc_cont, na.rm = TRUE)),
                                                                                                                              c(sd(forbiddenspeech$gender == 2, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$age5 >= 5, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$race == 1, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$race == 2, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$race == 4, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$race == 3, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$pid7 < 4, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$educ4>2,na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$employ < 4, na.rm = TRUE),
                                                                                                                                sd(forbiddenspeech$faminc_cont, na.rm = TRUE)))
)


##Calculate differences
# Define population values (see paper for sources)
population_values <- c(0.505, 0.177, 0.753, 0.137, 0.064, 0.195, 0.49, 0.343, 0.604, 114500)

# Define sample means and standard deviations
sample_means <- c(
  mean(forbiddenspeech$gender == 2, na.rm = TRUE),
  mean(forbiddenspeech$age5 >= 5, na.rm = TRUE),
  mean(forbiddenspeech$race == 1, na.rm = TRUE),
  mean(forbiddenspeech$race == 2, na.rm = TRUE),
  mean(forbiddenspeech$race == 4, na.rm = TRUE),
  mean(forbiddenspeech$race == 3, na.rm = TRUE),
  mean(forbiddenspeech$educ4>2,na.rm = TRUE),
  mean(forbiddenspeech$pid7 < 4, na.rm = TRUE),
  mean(forbiddenspeech$employ < 4, na.rm = TRUE),
  mean(forbiddenspeech$faminc_cont, na.rm = TRUE)
)

sample_sd <- c(
  sd(forbiddenspeech$gender == 2, na.rm = TRUE),
  sd(forbiddenspeech$age5 >= 5, na.rm = TRUE),
  sd(forbiddenspeech$race == 1, na.rm = TRUE),
  sd(forbiddenspeech$race == 2, na.rm = TRUE),
  sd(forbiddenspeech$race == 4, na.rm = TRUE),
  sd(forbiddenspeech$race == 3, na.rm = TRUE),
  sd(forbiddenspeech$educ4>2,na.rm = TRUE),
  sd(forbiddenspeech$pid7 < 4, na.rm = TRUE),
  sd(forbiddenspeech$employ < 4, na.rm = TRUE),
  sd(forbiddenspeech$faminc_cont, na.rm = TRUE)
)

# Sample size (given as 9486)
N <- 9486

# Compute mean difference
mean_diff <- sample_means - population_values

# Compute standard error of the mean difference
se_diff <- sample_sd / sqrt(N)
t_scores <- mean_diff / se_diff

# Compute two-tailed p-values using the t-distribution
p_values <- 2 * (1 - pt(abs(t_scores), df = N - 1))

# Create formatted data frame with mean difference and SE in square brackets
table_data <- data.frame(
  Variable = c("Female", "Over 65", "White", "Black", "Asian", "Hispanic", 
               "Democrat or Leans Democrat", "College graduate", "Employed", "Household Income"),
  USA_Mean = sprintf("%.3f", population_values),
  Sample_Mean = sprintf("%.3f\n(%.3f)", sample_means, sample_sd),  # Mean with SD in ()
  Mean_Difference = sprintf("%.3f\n[%.3f]", mean_diff, p_values)  # Mean diff with p-value in []
)

print(table_data)

# Convert the table to LaTeX format
latex_table <- xtable(table_data, digits = 3)
print(latex_table, include.rownames = FALSE, sanitize.text.function = identity)




###Table A7. AMCEs in main model, including covariates: coefficients, t statistic, and q-values
#Calculate q values
Maineffects.Covs<-lm(wouldconsidernotvoting ~ nature_severity+cong_responstarget+ response_simple2 +agg_circum2+incong_responscandidate +women+nonwhite+ageest+collegegrad+demlean+demlean+factor(res_region)+faminc_new,data=forbiddenspeech)


#Generate table
Mainpvalues <- summary(Maineffects.Covs)$coefficients[, 4]
Mainqvalues<-qvalue::qvalue(Mainpvalues, pi0 = 1, fdr.level=.05)

tableMaineffects<- cbind(summary(Maineffects.Covs)$coefficients[, 1],summary(Maineffects.Covs)$coefficients[, 3],Mainqvalues$qvalues)
rownames(tableMaineffects)

rownames(tableMaineffects) <- rev(c("Income","Region-West","Region-Midwest","Region-South","Democrat (incl. leaners)","College grads.","Age (cont.)","Nonwhite","Women", "Incongruence \n candidate-respondent",
                                    "Aggravating \n circumstances", 
                                    "Excuse", 
                                    "Apology",  
                                    "Defense", 
                                    "Congruence \n target-respond.",  
                                    "Slur","Dehumanizing", "Stereotype", "Denial",
                                    "Intercept"))


latex_table <- xtable(tableMaineffects, digits = 3)

# Print LaTeX table without row numbers
print(latex_table, include.rownames = TRUE, sanitize.text.function = identity)




#####END of analysis code####